import { ChangeDetectionStrategy, Component, Injector, OnInit } from '@angular/core';
import { ApiResToComponent } from '@basic';
import { SFSchema } from '@delon/form';
import { BaseOfSystemForm } from '@routes/system/_base';
import { MenuForm, MenuVO } from '@types';
import { Observable } from 'rxjs';

import { SystemDictService } from '../../dict/dict.service';
import { SystemMenuService } from '../menu.service';

@Component({
    selector: 'app-system-edit-menu',
    templateUrl: './edit-menu.component.html',
    styleUrls: ['./edit-menu.component.less'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class SystemEditMenuComponent extends BaseOfSystemForm<MenuForm, MenuVO> implements OnInit {
    protected makeParams(value: any): MenuForm {
        return value;
    }

    schema: SFSchema = {
        properties: {
            parentId: {
                type: 'string',
                title: '上级菜单',
                ui: {
                    widget: 'tree-select',
                    placeholder: '选择上级菜单',
                    virtualHeight: '300px',
                    spanLabel: 4,
                    spanControl: 8,
                    grid: {
                        span: 24
                    },
                    asyncData: () => this.menuSrv.menuTreeSelectSF()
                },
                default: 0
            },
            menuType: {
                type: 'string',
                title: '菜单类型',
                ui: {
                    widget: 'radio',
                    styleType: 'default',
                    buttonStyle: 'solid',
                    grid: {
                        span: 12
                    }
                },
                enum: [
                    { label: '目录', value: 'M' },
                    { label: '菜单', value: 'C' },
                    { label: '按钮', value: 'F' }
                ],
                default: 'M'
            },
            icon: {
                type: 'string',
                title: '菜单图标',
                ui: {
                    widget: 'icon',
                    grid: {
                        span: 12
                    },
                    visibleIf: {
                        menuType: val => (val !== 'F' ? { show: true } : null)
                    }
                }
            },
            menuName: {
                type: 'string',
                title: '菜单名称',
                ui: {
                    placeholder: '请输入菜单名称',
                    grid: {
                        span: 12
                    }
                }
            },
            orderNum: {
                type: 'number',
                title: '显示排序',
                ui: {
                    grid: {
                        span: 12
                    }
                },
                default: 0
            },
            isFrame: {
                type: 'string',
                title: '是否外链',
                ui: {
                    widget: 'radio',
                    styleType: 'default',
                    buttonStyle: 'solid',
                    grid: {
                        span: 12
                    },
                    visibleIf: {
                        menuType: val => (val !== 'F' ? { show: true } : null)
                    }
                },
                enum: [
                    { label: '是', value: '0' },
                    { label: '否', value: '1' }
                ],
                default: '1'
            },
            path: {
                type: 'string',
                title: '路由地址',
                ui: {
                    optionalHelp: '访问的路由地址，如：`user`，如外网地址需内链访问则以`http(s)://`开头',
                    placeholder: '请输入路由地址',
                    spanLabel: 4,
                    spanControl: 20,
                    grid: {
                        span: 24
                    },
                    visibleIf: {
                        menuType: val => (val !== 'F' ? { show: true, required: true } : null)
                    }
                }
            },
            component: {
                type: 'string',
                title: '组件路径',
                ui: {
                    optionalHelp: '访问的组件路径，如：`system/user/index`，默认在`views`目录下',
                    placeholder: '请输入组件路径',
                    spanLabel: 4,
                    spanControl: 20,
                    grid: {
                        span: 24
                    },
                    visibleIf: {
                        menuType: val => (val === 'C' ? { show: true } : null)
                    }
                }
            },
            perms: {
                type: 'string',
                title: '权限字符',
                ui: {
                    optionalHelp: "控制器中定义的权限字符，如：@SaCheckPermission('system:user:list')",
                    placeholder: '请输入权限标识',
                    grid: {
                        span: 12
                    },
                    visibleIf: {
                        menuType: val => (val !== 'M' ? { show: true } : null)
                    }
                }
            },
            queryParam: {
                type: 'string',
                title: '路由参数',
                ui: {
                    optionalHelp: '访问路由的默认传递参数，如：`{"id": 1, "name": "ry"}`',
                    placeholder: '请输入路由参数',
                    spanLabel: 4,
                    spanControl: 20,
                    grid: {
                        span: 24
                    },
                    visibleIf: {
                        menuType: val => (val === 'C' ? { show: true } : null)
                    }
                }
            },
            isCache: {
                type: 'string',
                title: '是否缓存',
                ui: {
                    optionalHelp: '选择是则会被`keep-alive`缓存，需要匹配组件的`name`和地址保持一致',
                    widget: 'radio',
                    styleType: 'default',
                    buttonStyle: 'solid',
                    grid: {
                        span: 12
                    },
                    visibleIf: {
                        menuType: val => (val === 'C' ? { show: true } : null)
                    }
                },
                enum: [
                    { label: '缓存', value: '0' },
                    { label: '不缓存', value: '1' }
                ],
                default: '0'
            },
            visible: {
                type: 'string',
                title: '显示状态',
                ui: {
                    optionalHelp: '选择隐藏则路由将不会出现在侧边栏，但仍然可以访问',
                    widget: 'radio',
                    styleType: 'default',
                    buttonStyle: 'solid',
                    grid: {
                        span: 12
                    },
                    asyncData: () => this.injector.get(SystemDictService).getDicts('sys_show_hide'),
                    visibleIf: {
                        menuType: val => (val !== 'F' ? { show: true } : null)
                    }
                },
                default: '0'
            },
            status: {
                type: 'string',
                title: '显示状态',
                ui: {
                    optionalHelp: '选择停用则路由将不会出现在侧边栏，也不能被访问',
                    widget: 'radio',
                    styleType: 'default',
                    buttonStyle: 'solid',
                    grid: {
                        span: 12
                    },
                    asyncData: () => this.injector.get(SystemDictService).getDicts('sys_normal_disable')
                },
                default: '0'
            }
        },
        required: ['menuName', 'orderNum'],
        ui: {
            spanLabel: 8,
            spanControl: 16,
            grid: {
                span: 24
            }
        }
    };

    sendToServer(value: any): Observable<ApiResToComponent<MenuVO>> {
        if (this.item.menuId) {
            return this.menuSrv.updateMenu(value);
        }
        return this.menuSrv.addMenu(value);
    }

    constructor(
        protected override injector: Injector,
        protected menuSrv: SystemMenuService
    ) {
        super(injector);
    }

    override ngOnInit() {
        if (this.item.menuId) {
            this.menuSrv.getMenu(this.item.menuId).subscribe(res => {
                this.item = res.data;
                this.cdRef.detectChanges();
            });
        }
    }
}
